import { app, shell, BrowserWindow, ipcMain, WebContentsView, dialog, Menu } from 'electron';
import { join } from 'path';
import { pathToFileURL } from 'url';
import { electronApp, optimizer, is } from '@electron-toolkit/utils';
import icon from '../../resources/icon.png?asset';
import axios from 'axios';
import https from 'https';
import WebSocket from 'ws';
import * as fs from 'fs';
import * as path from 'path';

const websocketConnections = new Map<string, WebSocket>();
const tabWebSocketConnections = new Map<string, Set<string>>();
const websocketToTab = new Map<string, string>();
type TabConnectionInfo = {
  tabId: string;
  connectionId?: string;
  sessionId?: string;
  webSessionId?: string;
  baseUrl?: string;
  csrfToken?: string;
  cookie?: { name: string; value: string };
  kvmSession?: KvmSessionPayload;
};
const tabConnectionInfos = new Map<string, TabConnectionInfo>();
type KvmSessionPayload = {
  kvmIp: string;
  kvmPort: number | string;
  sessionId: string;
  webSessionId: string;
  title: string;
  token: string;
  privilege: string;
  baseUrl: string;
  csrfToken: string;
  cookieName: string;
  cookieValue: string;
  loginIp: string;
  loginPort: string;
  useCertificate?: string;
};
type TabViewBounds = { x: number; y: number; width: number; height: number };
type TabCloseDecision = {
  tabId: string;
  shouldClose?: boolean;
  saveInfo?: { ip: string; port: number };
};
const tabViews = new Map<string, WebContentsView>();
const pendingTabCloseResolvers = new Map<string, (value: TabCloseDecision | undefined) => void>();
const EMPTY_BOUNDS: TabViewBounds = { x: 0, y: 0, width: 0, height: 0 };
let activeTabId: string | null = null;
let mainWindow: BrowserWindow | null = null;
let isShuttingDown = false;
type TrustedSite = {
  id: string;
  ip: string;
  createdAt: string;
  updatedAt: string;
};
const trustedSitesList = new Map<string, TrustedSite>();

// 信任站点存储文件
function getTrustedSitesListFilePath(): string {
  const userDataPath = app.getPath('userData');
  return path.join(userDataPath, 'trusted-sites-list.json');
}

// 从文件加载信任站点列表
function loadTrustedSitesListFromFile(): void {
  try {
    const filePath = getTrustedSitesListFilePath();
    if (fs.existsSync(filePath)) {
      const data = fs.readFileSync(filePath, 'utf-8');
      const certificates: TrustedSite[] = JSON.parse(data);
      trustedSitesList.clear();
      for (const cert of certificates) {
        const key = getCertificateKey(cert.ip);
        trustedSitesList.set(key, cert);
      }
    }
  } catch (error) {
    console.error('Failed to load trusted sites from file:', error);
  }
}

// 保存信任站点列表到文件
function saveTrustedSitesListToFile(): void {
  try {
    const filePath = getTrustedSitesListFilePath();
    const certificates = Array.from(trustedSitesList.values());
    fs.writeFileSync(filePath, JSON.stringify(certificates, null, 2), 'utf-8');
  } catch (error) {
    console.error('Failed to save trusted sites to file:', error);
  }
}

function ensureMainWindow(): BrowserWindow {
  if (!mainWindow) {
    throw new Error('Main window is not initialized');
  }
  return mainWindow;
}

function normalizeBounds(bounds: TabViewBounds | undefined): TabViewBounds {
  if (!bounds) {
    throw new Error('Bounds must be provided');
  }
  return {
    x: Math.round(bounds.x),
    y: Math.round(bounds.y),
    width: Math.max(0, Math.round(bounds.width)),
    height: Math.max(0, Math.round(bounds.height))
  };
}

function resolveLoginUrl(tabId?: string, extraQuery?: Record<string, string>): string {
  const params = new URLSearchParams();
  if (tabId) {
    params.set('tabId', tabId);
  }
  if (extraQuery) {
    for (const [key, value] of Object.entries(extraQuery)) {
      if (value !== undefined && value !== null) {
        params.set(key, String(value));
      }
    }
  }
  const hash = params.toString() ? `#/login?${params.toString()}` : '#/login';
  if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
    return `${process.env['ELECTRON_RENDERER_URL']}${hash}`;
  }
  const fileUrl = pathToFileURL(join(__dirname, '../renderer/index.html'));
  fileUrl.hash = hash;
  return fileUrl.toString();
}

function hideActiveView(): void {
  if (!activeTabId) {
    return;
  }
  const activeView = tabViews.get(activeTabId);
  activeView?.setBounds(EMPTY_BOUNDS);
}

function createWindow(): void {
  // Create the browser window.
  mainWindow = new BrowserWindow({
    width: 1440,
    height: 900,
    minWidth: 1440,
    minHeight: 900,
    show: false,
    autoHideMenuBar: false,
    ...(process.platform === 'linux' ? { icon } : {}),
    webPreferences: {
      preload: join(__dirname, '../preload/index.js'),
      sandbox: false
    }
  });

  Menu.setApplicationMenu(null);

  mainWindow.on('ready-to-show', () => {
    mainWindow?.show();
  });

  mainWindow.webContents.setWindowOpenHandler((details) => {
    shell.openExternal(details.url);
    return { action: 'deny' };
  });

  // HMR for renderer base on electron-vite cli.
  // Load the remote URL for development or the local html file for production.
  if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
    mainWindow.loadURL(process.env['ELECTRON_RENDERER_URL']);
  } else {
    mainWindow.loadFile(join(__dirname, '../renderer/index.html'));
  }
  mainWindow.on('closed', () => {
    editDialogWindows.forEach((window) => {
      if (!window.isDestroyed()) {
        window.close();
      }
    });
    editDialogWindows.clear();

    deleteDialogWindows.forEach((window) => {
      if (!window.isDestroyed()) {
        window.close();
      }
    });
    deleteDialogWindows.clear();

    mainWindow = null;
    tabViews.clear();
    activeTabId = null;
  });
}
// 关闭指定tab的所有 WebSocket 连接
function closeTabWebSocketConnections(tabId: string): void {
  const connectionIds = tabWebSocketConnections.get(tabId);
  if (!connectionIds || connectionIds.size === 0) {
    return;
  }

  connectionIds.forEach((connectionId) => {
    const websocket = websocketConnections.get(connectionId);
    if (websocket) {
      try {
        if (
          websocket.readyState === WebSocket.OPEN ||
          websocket.readyState === WebSocket.CONNECTING
        ) {
          websocket.close();
        } else {
          websocket.terminate();
        }
      } catch (error) {
        console.error(`关闭 WebSocket 连接失败 [${connectionId}]:`, error);
      }
      websocketConnections.delete(connectionId);
      websocketToTab.delete(connectionId);
    }
  });

  tabWebSocketConnections.delete(tabId);
}

// 关闭所有 WebSocket 连接
function closeAllWebSocketConnections(): void {
  if (websocketConnections.size === 0) {
    return;
  }
  websocketConnections.forEach((websocket, connectionId) => {
    try {
      if (
        websocket.readyState === WebSocket.OPEN ||
        websocket.readyState === WebSocket.CONNECTING
      ) {
        websocket.close();
      } else {
        websocket.terminate();
      }
    } catch (error) {
      console.error(`关闭 WebSocket 连接失败: ${connectionId}`, error);
    }
  });
  websocketConnections.clear();
  tabWebSocketConnections.clear();
  websocketToTab.clear();
}

// 退出指定tab的会话
async function logoutTabSession(tabId: string, trigger: string): Promise<void> {
  const info = tabConnectionInfos.get(tabId);
  if (!info) {
    return;
  }

  const httpsAgent = new https.Agent({
    rejectUnauthorized: false
  });

  await logoutConnectionInfo(info, trigger, httpsAgent, tabId);
  tabConnectionInfos.delete(tabId);
}

function logoutSession(
  baseUrl: string,
  sessionId: string,
  csrfToken: string,
  cookie: { name: string; value: string },
  httpsAgent: https.Agent,
  trigger: string,
  sessionType: 'KVM' | 'Web',
  tabId?: string
): Promise<void> {
  const logoutUrl = `${baseUrl}/UI/Rest/Sessions/${sessionId}`;
  const tabInfo = tabId ? `tabId: ${tabId}, ` : '';
  return axios({
    method: 'delete',
    url: logoutUrl,
    headers: {
      From: 'WebUI',
      'X-CSRF-Token': csrfToken,
      cookie: `${cookie.name}=${cookie.value}`
    },
    httpsAgent
  })
    .then(() => {
      console.log(
        `${sessionType} 会话退出成功 (trigger: ${trigger}, ${tabInfo}sessionId: ${sessionId})`
      );
    })
    .catch((error) => {
      console.error(
        `${sessionType} 会话退出失败 (trigger: ${trigger}, ${tabInfo}sessionId: ${sessionId})`,
        error
      );
    });
}

async function logoutConnectionInfo(
  info: TabConnectionInfo,
  trigger: string,
  httpsAgent: https.Agent,
  tabId?: string
): Promise<void> {
  const baseUrl = info.baseUrl;
  const csrfToken = info.csrfToken;
  const cookie = info.cookie;
  if (!baseUrl || !csrfToken || !cookie?.name || !cookie?.value) {
    return;
  }

  const logoutPromises: Promise<void>[] = [];

  // 退出 KVM 会话
  if (info.sessionId) {
    logoutPromises.push(
      logoutSession(baseUrl, info.sessionId, csrfToken, cookie, httpsAgent, trigger, 'KVM', tabId)
    );
  }

  // 退出 Web 会话
  if (info.webSessionId && info.webSessionId !== info.sessionId) {
    logoutPromises.push(
      logoutSession(
        baseUrl,
        info.webSessionId,
        csrfToken,
        cookie,
        httpsAgent,
        trigger,
        'Web',
        tabId
      )
    );
  }

  await Promise.all(logoutPromises);
}

async function logoutAllSessions(trigger: string): Promise<void> {
  if (tabConnectionInfos.size === 0) {
    return;
  }
  const httpsAgent = new https.Agent({
    rejectUnauthorized: false
  });
  const tasks = Array.from(tabConnectionInfos.values()).map((info) =>
    logoutConnectionInfo(info, trigger, httpsAgent)
  );
  await Promise.all(tasks);
  tabConnectionInfos.clear();
}

async function gracefulShutdown(): Promise<void> {
  if (isShuttingDown) {
    return;
  }
  isShuttingDown = true;

  // 通知所有渲染进程应用即将关闭
  if (mainWindow && !mainWindow.isDestroyed()) {
    mainWindow.webContents.send('app-will-quit');
  }

  // 通知所有tab应用即将关闭
  tabViews.forEach((view) => {
    if (!view.webContents.isDestroyed()) {
      view.webContents.send('app-will-quit');
    }
  });

  // 关闭所有WebSocket连接
  closeAllWebSocketConnections();

  // 退出所有会话
  await logoutAllSessions('app-before-quit');
}
// WebSocket连接
function createWebSocketConnection(
  connectionId: string,
  url: string,
  event: any,
  rejectUnauthorized?: boolean
): WebSocket {
  // 如果已存在相同ID的连接，先关闭并清理
  if (websocketConnections.has(connectionId)) {
    const existingConnection = websocketConnections.get(connectionId);
    if (existingConnection) {
      if (
        existingConnection.readyState === WebSocket.OPEN ||
        existingConnection.readyState === WebSocket.CONNECTING
      ) {
        try {
          existingConnection.close();
        } catch (error) {
          console.warn(`关闭现有 WebSocket 连接时出错 [${connectionId}]:`, error);
        }
      } else {
        // 如果连接已经关闭或正在关闭，直接终止
        try {
          existingConnection.terminate();
        } catch (error) {
          console.warn(`终止现有 WebSocket 连接时出错 [${connectionId}]:`, error);
        }
      }
      const oldTabId = websocketToTab.get(connectionId);
      if (oldTabId) {
        const oldTabConnections = tabWebSocketConnections.get(oldTabId);
        if (oldTabConnections) {
          oldTabConnections.delete(connectionId);
          if (oldTabConnections.size === 0) {
            tabWebSocketConnections.delete(oldTabId);
          }
        }
        websocketToTab.delete(connectionId);
      }
      websocketConnections.delete(connectionId);
    }
  }
  const ipPort = extractIpAndPort(url);
  let shouldRejectUnauthorized = rejectUnauthorized === true;
  if (ipPort && isTrustedSite(ipPort.ip)) {
    shouldRejectUnauthorized = false;
  }
  const agent = new https.Agent({
    rejectUnauthorized: shouldRejectUnauthorized
  });
  const websocket = new WebSocket(url, {
    agent: agent
  });
  websocket.binaryType = 'arraybuffer';
  websocket.onopen = () => {
    event.sender.send('websocket-status', {
      connectionId,
      status: 'connected',
      url
    });
  };

  websocket.onmessage = (message) => {
    event.sender.send('websocket-message', {
      connectionId,
      data: message.data,
      timestamp: new Date().toISOString()
    });
  };

  websocket.onerror = (error: any) => {
    const errorMessage = error?.message || error?.toString() || '';
    const errorCode = error?.code || '';
    event.sender.send('websocket-error', {
      connectionId,
      error: errorMessage || error?.toString() || 'WebSocket connection error',
      code: errorCode
    });
  };

  websocket.onclose = (closeEvent) => {
    event.sender.send('websocket-status', {
      connectionId,
      status: 'disconnected',
      code: closeEvent.code,
      reason: closeEvent.reason
    });

    // 获取该连接所属的tabId
    const tabId = websocketToTab.get(connectionId);

    // 清理连接
    websocketConnections.delete(connectionId);
    websocketToTab.delete(connectionId);
    if (tabId) {
      const tabConnections = tabWebSocketConnections.get(tabId);
      if (tabConnections) {
        tabConnections.delete(connectionId);
        if (tabConnections.size === 0) {
          tabWebSocketConnections.delete(tabId);
        }
      }
    }
  };
  // 存储连接
  websocketConnections.set(connectionId, websocket);

  return websocket;
}

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(() => {
  // Set app user model id for windows
  electronApp.setAppUserModelId('com.electron');

  // 加载信任站点列表
  loadTrustedSitesListFromFile();

  app.on('browser-window-created', (_, window) => {
    optimizer.watchWindowShortcuts(window);
  });

  createWindow();

  app.on('activate', function () {
    // On macOS it's common to re-create a window in the app when the
    // dock icon is clicked and there are no other windows open.
    if (BrowserWindow.getAllWindows().length === 0) createWindow();
  });
});

// 在应用退出前关闭连接和会话
app.on('before-quit', (event) => {
  if (isShuttingDown) {
    return;
  }
  event.preventDefault();
  void gracefulShutdown().finally(() => {
    app.exit();
  });
});

// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit();
  }
});

// WebSocket IPC
ipcMain.handle(
  'websocket-connect',
  async (event, { connectionId, url, rejectUnauthorized, tabId }) => {
    try {
      createWebSocketConnection(connectionId, url, event, rejectUnauthorized);

      if (tabId) {
        if (!tabWebSocketConnections.has(tabId)) {
          tabWebSocketConnections.set(tabId, new Set());
        }
        tabWebSocketConnections.get(tabId)!.add(connectionId);
        websocketToTab.set(connectionId, tabId);
      }

      return { success: true, message: 'WebSocket connection initiated' };
    } catch (error) {
      const message = error instanceof Error ? error.message : String(error);
      return { success: false, error: message };
    }
  }
);

// msg数据处理
ipcMain.handle('websocket-send', async (_event, { connectionId, data }) => {
  try {
    const websocket = websocketConnections.get(connectionId);
    if (!websocket || websocket.readyState !== WebSocket.OPEN) {
      throw new Error('WebSocket is not connected');
    }

    let payload: Buffer;
    if (data instanceof ArrayBuffer) {
      payload = Buffer.from(data);
    } else if (ArrayBuffer.isView(data)) {
      payload = Buffer.from(data.buffer, data.byteOffset, data.byteLength);
    } else if (Buffer.isBuffer(data)) {
      payload = data;
    } else if (typeof data === 'string') {
      payload = Buffer.from(data);
    } else {
      payload = Buffer.from(data);
    }
    websocket.send(payload);
    return { success: true, message: 'Message sent' };
  } catch (error) {
    const message = error instanceof Error ? error.message : String(error);
    return { success: false, error: message };
  }
});

ipcMain.handle('websocket-disconnect', async (_event, connectionId) => {
  try {
    const websocket = websocketConnections.get(connectionId);
    if (websocket) {
      if (
        websocket.readyState === WebSocket.OPEN ||
        websocket.readyState === WebSocket.CONNECTING
      ) {
        try {
          websocket.close();
        } catch (error) {
          console.warn(`关闭 WebSocket 连接时出错 [${connectionId}]:`, error);
          try {
            websocket.terminate();
          } catch (terminateError) {
            console.warn(`终止 WebSocket 连接时出错 [${connectionId}]:`, terminateError);
          }
        }
      } else {
        // 如果连接已经关闭或正在关闭，直接终止
        try {
          websocket.terminate();
        } catch (error) {
          console.warn(`终止 WebSocket 连接时出错 [${connectionId}]:`, error);
        }
      }

      websocketConnections.delete(connectionId);
      const tabId = websocketToTab.get(connectionId);
      if (tabId) {
        const tabConnections = tabWebSocketConnections.get(tabId);
        if (tabConnections) {
          tabConnections.delete(connectionId);
          if (tabConnections.size === 0) {
            tabWebSocketConnections.delete(tabId);
          }
        }
        websocketToTab.delete(connectionId);
      }
    }

    return { success: true, message: 'WebSocket disconnected' };
  } catch (error) {
    console.error('WebSocket disconnect failed:', error);
    const message = error instanceof Error ? error.message : String(error);
    return { success: false, error: message };
  }
});

ipcMain.handle('websocket-get-connections', async () => {
  const connections = Array.from(websocketConnections.entries()).map(([id, ws]) => ({
    id,
    readyState: ws.readyState,
    url: ws.url
  }));
  return { success: true, connections };
});

ipcMain.handle(
  'tab-view-create',
  async (
    _event,
    payload: { tabId: string; bounds: TabViewBounds; options?: { query?: Record<string, string> } }
  ) => {
    const targetWindow = ensureMainWindow();
    const { tabId, bounds: _bounds, options } = payload;
    if (!tabId) {
      throw new Error('tabId is required');
    }
    if (tabViews.has(tabId)) {
      return { success: true };
    }
    const view = new WebContentsView({
      webPreferences: {
        preload: join(__dirname, '../preload/index.js'),
        sandbox: false
      }
    });
    tabViews.set(tabId, view);
    await view.webContents.loadURL(resolveLoginUrl(tabId, options?.query));
    targetWindow.contentView.addChildView(view);
    view.setBounds(EMPTY_BOUNDS);
    return { success: true };
  }
);

ipcMain.handle(
  'tab-view-activate',
  async (_event, payload: { tabId: string; bounds: TabViewBounds }) => {
    const { tabId, bounds } = payload;
    if (!tabId) {
      throw new Error('tabId is required');
    }
    const view = tabViews.get(tabId);
    if (!view) {
      throw new Error(`No WebContentsView for tabId ${tabId}`);
    }
    const normalizedBounds = normalizeBounds(bounds);
    if (activeTabId !== tabId) {
      hideActiveView();
      activeTabId = tabId;
    }
    view.setBounds(normalizedBounds);
    return { success: true };
  }
);

ipcMain.handle('tab-view-resize', (_event, payload: { tabId: string; bounds: TabViewBounds }) => {
  const { tabId, bounds } = payload;
  if (!tabId) {
    throw new Error('tabId is required');
  }
  const view = tabViews.get(tabId);
  if (!view) {
    return { success: false, error: `No WebContentsView for tabId ${tabId}` };
  }
  const normalizedBounds = normalizeBounds(bounds);
  if (activeTabId === tabId) {
    view.setBounds(normalizedBounds);
  }
  return { success: true };
});

ipcMain.handle(
  'kvm-session-save',
  async (_event, payload: { tabId: string; session: KvmSessionPayload }) => {
    const { tabId, session } = payload || {};
    if (!tabId) {
      throw new Error('tabId is required');
    }
    if (!session) {
      throw new Error('session payload is required');
    }
    const info = tabConnectionInfos.get(tabId) || { tabId };
    info.kvmSession = session;
    tabConnectionInfos.set(tabId, info);
    return { success: true };
  }
);

ipcMain.handle('kvm-session-get', async (_event, payload: { tabId: string }) => {
  const { tabId } = payload || {};
  if (!tabId) {
    throw new Error('tabId is required');
  }
  const info = tabConnectionInfos.get(tabId);
  const session = info?.kvmSession;
  return { success: Boolean(session), session };
});

ipcMain.handle('kvm-session-clear', async (_event, payload: { tabId: string }) => {
  const { tabId } = payload || {};
  if (!tabId) {
    throw new Error('tabId is required');
  }
  const info = tabConnectionInfos.get(tabId);
  if (info) {
    delete info.kvmSession;
    tabConnectionInfos.set(tabId, info);
  }
  return { success: true };
});

ipcMain.handle('tab-view-destroy', async (_event, tabId: string) => {
  if (!tabId) {
    throw new Error('tabId is required');
  }
  const view = tabViews.get(tabId);
  if (!view) {
    return { success: true };
  }

  // 关闭该tab的所有WebSocket连接
  closeTabWebSocketConnections(tabId);

  // 退出该tab的会话登录
  await logoutTabSession(tabId, `tab-destroy-${tabId}`);

  const parentView = mainWindow?.contentView;
  parentView?.removeChildView(view);
  // WebContentsView在移除时自动清理
  tabViews.delete(tabId);
  tabConnectionInfos.delete(tabId);
  if (activeTabId === tabId) {
    activeTabId = null;
  }
  const resolver = pendingTabCloseResolvers.get(tabId);
  if (resolver) {
    pendingTabCloseResolvers.delete(tabId);
    resolver({ tabId, shouldClose: true });
  }
  return { success: true };
});

ipcMain.handle('tab-view-request-close', async (_event, tabId: string) => {
  if (!tabId) {
    throw new Error('tabId is required');
  }
  const view = tabViews.get(tabId);
  if (!view) {
    return { tabId, shouldClose: true };
  }
  return await new Promise<TabCloseDecision>((resolve) => {
    pendingTabCloseResolvers.set(tabId, (value) => {
      pendingTabCloseResolvers.delete(tabId);
      resolve(value ?? { tabId, shouldClose: true });
    });
    view.webContents.send('tab-close-request', { tabId });
  });
});

ipcMain.on('tab-close-response', (_event, payload: TabCloseDecision) => {
  if (!payload?.tabId) {
    return;
  }
  const resolver = pendingTabCloseResolvers.get(payload.tabId);
  if (resolver) {
    pendingTabCloseResolvers.delete(payload.tabId);
    resolver(payload);
  }
});

ipcMain.on('tab-conn-info-report', (_event, payload) => {
  if (!payload?.tabId) {
    return;
  }
  if (payload.clear) {
    tabConnectionInfos.delete(payload.tabId);
  } else {
    tabConnectionInfos.set(payload.tabId, payload);
  }
  if (mainWindow && !mainWindow.isDestroyed()) {
    mainWindow.webContents.send('tab-conn-info', payload);
  }
});

ipcMain.on('tab-title-report', (_event, payload: { tabId?: string; title?: string }) => {
  if (!payload?.tabId || !payload?.title) {
    return;
  }
  if (mainWindow && !mainWindow.isDestroyed()) {
    mainWindow.webContents.send('tab-title-updated', {
      tabId: payload.tabId,
      title: payload.title
    });
  }
});

ipcMain.handle('tab-view-find-existing-connection', async (_event, { ip, port }) => {
  try {
    const targetWindow = ensureMainWindow();
    if (targetWindow.isDestroyed()) {
      return { tabId: null };
    }
    const result = await targetWindow.webContents.executeJavaScript(
      `(function() {
        if (typeof window.findExistingConnection === 'function') {
          return window.findExistingConnection(${JSON.stringify(ip)}, ${port});
        }
        return null;
      })()`
    );
    return { tabId: result };
  } catch (error) {
    console.error('Failed to find existing connection:', error);
    return { tabId: null };
  }
});

ipcMain.handle('tab-view-activate-tab', async (_event, { tabId }) => {
  try {
    const targetWindow = ensureMainWindow();
    if (targetWindow.isDestroyed()) {
      return { success: false };
    }
    await targetWindow.webContents.executeJavaScript(
      `(function() {
        if (window.activateExistingTab && typeof window.activateExistingTab === 'function') {
          window.activateExistingTab(${JSON.stringify(tabId)});
        }
      })()`
    );
    return { success: true };
  } catch (error) {
    console.error('Failed to activate tab:', error);
    return { success: false };
  }
});

// 处理重复连接，激活已存在的tab
ipcMain.on('duplicate-connection-notify', async (_event, { ip, port, tabId }) => {
  try {
    if (!tabId) {
      return;
    }
    const targetWindow = ensureMainWindow();
    if (targetWindow.isDestroyed()) {
      return;
    }
    await targetWindow.webContents.executeJavaScript(
      `(function() {
        if (window.activateExistingTab && typeof window.activateExistingTab === 'function') {
          window.activateExistingTab(${JSON.stringify(tabId)});
        }
      })()`
    );
    if (!targetWindow.isDestroyed()) {
      targetWindow.webContents.send('duplicate-connection-activated', { ip, port, tabId });
    }
  } catch (error) {
    console.error('Failed to handle duplicate connection notify:', error);
  }
});

function isSuccessResponse(status: number): boolean {
  return status >= 200 && status < 300;
}

function extractErrorMessage(response: any): string {
  if (
    response?.data?.error &&
    Array.isArray(response.data.error) &&
    response.data.error.length > 0
  ) {
    const firstError = response.data.error[0];
    if (firstError.code) {
      return firstError.code;
    }
    if (firstError.message) {
      return firstError.message;
    }
  }
  if (response?.status) {
    return `请求失败 (状态码: ${response.status})`;
  }
  return '请求失败';
}

function handleNetworkError(error: any): string {
  if (!error?.message) {
    return '请求失败，请检查网络连接和服务器地址';
  }
  return error.message;
}

function extractIpAndPort(url: string): { ip: string; port: number } | null {
  try {
    const urlObj = new URL(url);
    const hostname = urlObj.hostname;
    const port = urlObj.port ? parseInt(urlObj.port, 10) : urlObj.protocol === 'https:' ? 443 : 80;

    const ipPattern = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/;
    if (ipPattern.test(hostname)) {
      return { ip: hostname, port };
    }
  } catch (error) {
    console.error('Failed to extract IP and port from URL:', error);
  }
  return null;
}

function getCertificateKey(ip: string): string {
  return ip;
}

// 检查IP是否在可信列表中
function isTrustedSite(ip: string): boolean {
  return trustedSitesList.has(getCertificateKey(ip));
}

// 添加可信站点
function addTrustedSite(ip: string): void {
  const key = getCertificateKey(ip);
  const now = new Date().toISOString();

  if (trustedSitesList.has(key)) {
    const existing = trustedSitesList.get(key)!;
    existing.updatedAt = now;
  } else {
    const cert: TrustedSite = {
      id: `${ip}:${Date.now()}`,
      ip,
      createdAt: now,
      updatedAt: now
    };
    trustedSitesList.set(key, cert);
  }

  saveTrustedSitesListToFile();
}

ipcMain.handle('fetch-data', async (_event, params) => {
  // 从URL中提取IP和Port
  const ipPort = extractIpAndPort(params.url);

  try {
    // 检查是否在可信列表中
    let shouldRejectUnauthorized = params.rejectUnauthorized === true;
    if (ipPort && isTrustedSite(ipPort.ip)) {
      // 如果在可信列表中，则不验证证书
      shouldRejectUnauthorized = false;
    }

    const httpsAgent = new https.Agent({
      rejectUnauthorized: shouldRejectUnauthorized
    });

    let requestData = params.data;
    let requestHeaders = params.headers ? { ...params.headers } : {};

    if (params.data?.formDataEntries && Array.isArray(params.data.formDataEntries)) {
      const FormData = require('form-data');
      const formData = new FormData();

      for (const entry of params.data.formDataEntries) {
        if (entry.isFile) {
          const buffer = Buffer.from(entry.value);
          formData.append(entry.key, buffer, {
            filename: entry.fileName || 'file',
            contentType: entry.mimeType || 'application/octet-stream'
          });
        } else {
          formData.append(entry.key, entry.value);
        }
      }

      requestData = formData;
      requestHeaders = {
        ...requestHeaders,
        ...formData.getHeaders()
      };
    }

    const requestConfig = {
      method: params.method,
      url: params.url,
      httpsAgent: httpsAgent,
      headers: requestHeaders,
      params: params.params || {},
      ...(requestData !== undefined && { data: requestData }),
      withCredentials: true
    };
    const res = await axios(requestConfig);

    const isSuccess = isSuccessResponse(res.status);
    return {
      success: isSuccess,
      headers: res.headers,
      data: res.data,
      status: res.status,
      statusText: res.statusText,
      errorMessage: isSuccess ? undefined : extractErrorMessage(res)
    };
  } catch (err) {
    if (axios.isAxiosError(err) && err.response) {
      const response = err.response;
      const isSuccess = isSuccessResponse(response.status);
      return {
        success: isSuccess,
        status: response.status,
        statusText: response.statusText,
        data: response.data,
        headers: response.headers,
        errorMessage: isSuccess ? undefined : extractErrorMessage(response)
      };
    }

    const errorMessage = handleNetworkError(err);
    return {
      success: false,
      status: 500,
      statusText: errorMessage,
      data: null,
      headers: {},
      errorMessage: errorMessage
    };
  }
});

// 帮助窗口管理
let helpWindow: BrowserWindow | null = null;

function resolveHelpUrl(): string {
  const hash = '#/help';
  if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
    const url = `${process.env['ELECTRON_RENDERER_URL']}${hash}`;
    return url;
  }
  const fileUrl = pathToFileURL(join(__dirname, '../renderer/index.html'));
  fileUrl.hash = hash;
  const finalUrl = fileUrl.toString();
  return finalUrl;
}

// 询问用户是否信任站点
ipcMain.handle('dialog-ask-trust-site', async (_event, { ip, texts }) => {
  try {
    const targetWindow = ensureMainWindow();
    const result = await dialog.showMessageBox(targetWindow, {
      type: 'warning',
      title: texts?.title ?? '连接不安全',
      message: texts?.message ?? `当前连接到 ${ip} 的不是私密连接`,
      detail: texts?.detail ?? '是否信任此站点并继续？选择"信任并继续"将保存此站点为可信站点。',
      buttons: texts?.buttons ?? ['信任并继续', '取消'],
      defaultId: 1,
      cancelId: 1,
      noLink: true
    });
    return { response: result.response, checkboxChecked: result.checkboxChecked };
  } catch (error) {
    console.error('Failed to show trust site dialog:', error);
    throw error;
  }
});

// 检查IP是否在可信列表中
ipcMain.handle('is-trusted-site', async (_event, { ip }) => {
  try {
    if (ip) {
      return { isTrusted: isTrustedSite(ip) };
    }
    return { isTrusted: false };
  } catch (error) {
    console.error('Failed to check trusted site:', error);
    return { isTrusted: false };
  }
});

// 获取所有信任站点列表
ipcMain.handle('get-trusted-sites-list', async () => {
  try {
    const certificates = Array.from(trustedSitesList.values());
    return { success: true, certificates };
  } catch (error) {
    console.error('Failed to get trusted sites:', error);
    return { success: false, error: error instanceof Error ? error.message : String(error) };
  }
});

// 添加可信站点
ipcMain.handle('add-trusted-site', async (_event, { ip }) => {
  try {
    if (ip) {
      addTrustedSite(ip);
      return { success: true };
    }
    return { success: false, error: 'IP不能为空' };
  } catch (error) {
    console.error('Failed to add trusted site:', error);
    return { success: false, error: error instanceof Error ? error.message : String(error) };
  }
});

// 更新可信站点
ipcMain.handle('update-trusted-site', async (_event, { id, ip }) => {
  try {
    if (!id || !ip) {
      return { success: false, error: 'ID和IP不能为空' };
    }

    const key = getCertificateKey(ip);
    const cert = trustedSitesList.get(key);

    if (!cert || cert.id !== id) {
      for (const [oldKey, oldCert] of trustedSitesList.entries()) {
        if (oldCert.id === id) {
          trustedSitesList.delete(oldKey);
          break;
        }
      }
      addTrustedSite(ip);
    } else {
      cert.updatedAt = new Date().toISOString();
      saveTrustedSitesListToFile();
    }

    return { success: true };
  } catch (error) {
    console.error('Failed to update trusted site:', error);
    return { success: false, error: error instanceof Error ? error.message : String(error) };
  }
});

// 删除可信站点
ipcMain.handle('delete-trusted-site', async (_event, { id, ip }) => {
  try {
    if (!id || !ip) {
      return { success: false, error: 'ID和IP不能为空' };
    }

    const key = getCertificateKey(ip);
    const cert = trustedSitesList.get(key);

    if (cert && cert.id === id) {
      trustedSitesList.delete(key);
      saveTrustedSitesListToFile();
      return { success: true };
    }

    return { success: false, error: '未找到要删除的站点' };
  } catch (error) {
    console.error('Failed to delete trusted site:', error);
    return { success: false, error: error instanceof Error ? error.message : String(error) };
  }
});

// 编辑对话框窗口管理
const editDialogWindows = new Map<string, BrowserWindow>();

function resolveEditDialogUrl(connectionId: string, connectionData: any): string {
  const params = new URLSearchParams();
  params.set('connectionId', connectionId);
  if (connectionData) {
    params.set('id', connectionData.id || '');
    params.set('ip', connectionData.ip || '');
    params.set('port', String(connectionData.port || ''));
    params.set('label', connectionData.label || '');
  }
  const hash = `#/edit-connection?${params.toString()}`;
  if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
    const url = `${process.env['ELECTRON_RENDERER_URL']}${hash}`;
    return url;
  }
  const fileUrl = pathToFileURL(join(__dirname, '../renderer/index.html'));
  fileUrl.hash = hash;
  const finalUrl = fileUrl.toString();
  return finalUrl;
}

// 创建编辑窗口
ipcMain.handle('dialog-show-edit-connection', async (_event, connectionData) => {
  try {
    const targetWindow = ensureMainWindow();
    const connectionId = connectionData?.id || `edit-${Date.now()}`;

    const existingWindow = editDialogWindows.get(connectionId);
    if (existingWindow && !existingWindow.isDestroyed()) {
      existingWindow.close();
      editDialogWindows.delete(connectionId);
    }

    const dialogUrl = resolveEditDialogUrl(connectionId, connectionData);

    const mainBounds = targetWindow.getBounds();
    const windowWidth = 600;
    const windowHeight = 400;
    const x = Math.round(mainBounds.x + (mainBounds.width - windowWidth) / 2);
    const y = Math.round(mainBounds.y + (mainBounds.height - windowHeight) / 2);

    const editWindow = new BrowserWindow({
      parent: targetWindow,
      modal: true,
      width: windowWidth,
      height: windowHeight,
      x: x,
      y: y,
      resizable: true,
      minimizable: false,
      show: false,
      autoHideMenuBar: true,
      ...(process.platform === 'linux' ? { icon } : {}),
      webPreferences: {
        preload: join(__dirname, '../preload/index.js'),
        sandbox: false,
        contextIsolation: true,
        nodeIntegration: false
      }
    });

    editDialogWindows.set(connectionId, editWindow);
    editWindow.on('closed', () => {
      editDialogWindows.delete(connectionId);
    });

    editWindow.webContents.on('did-fail-load', () => {
      if (!editWindow.isDestroyed()) {
        editWindow.close();
      }
    });

    editWindow.once('ready-to-show', () => {
      console.log('Edit dialog window ready-to-show event fired');
    });

    const loadPromise = new Promise<void>((resolve, reject) => {
      let resolved = false;
      const timeout = setTimeout(() => {
        if (!resolved) {
          resolved = true;
          resolve();
        }
      }, 3000);

      editWindow.webContents.once('did-finish-load', () => {
        if (!resolved) {
          resolved = true;
          clearTimeout(timeout);
          resolve();
        }
      });

      editWindow.webContents.once('did-fail-load', (_event, _errorCode, errorDescription) => {
        if (!resolved) {
          resolved = true;
          clearTimeout(timeout);
          reject(new Error(`加载失败: ${errorDescription}`));
        }
      });
    });

    try {
      await editWindow.loadURL(dialogUrl);
      await loadPromise;

      if (!editWindow.isDestroyed()) {
        editWindow.show();
        editWindow.focus();
      } else {
        console.warn('Edit dialog window was destroyed before showing');
      }
    } catch (loadError) {
      if (!editWindow.isDestroyed()) {
        editWindow.close();
      }
      throw loadError;
    }

    return { success: true, connectionId };
  } catch (error) {
    return { success: false, error: error instanceof Error ? error.message : String(error) };
  }
});

// 关闭编辑
ipcMain.handle('dialog-close-edit-connection', async (_event, connectionId) => {
  try {
    const editWindow = editDialogWindows.get(connectionId);
    if (editWindow && !editWindow.isDestroyed()) {
      editWindow.close();
      editDialogWindows.delete(connectionId);
    }
    return { success: true };
  } catch (error) {
    console.error('Failed to close edit dialog:', error);
    throw error;
  }
});

// 保存编辑
ipcMain.on('edit-connection-save', (_event, { connectionId, data }) => {
  if (mainWindow && !mainWindow.isDestroyed()) {
    mainWindow.webContents.send('edit-connection-saved', { connectionId, data });
  }
  const editWindow = editDialogWindows.get(connectionId);
  if (editWindow && !editWindow.isDestroyed()) {
    editWindow.close();
  }
});

// 取消编辑
ipcMain.on('edit-connection-cancel', (_event, connectionId) => {
  const editWindow = editDialogWindows.get(connectionId);
  if (editWindow && !editWindow.isDestroyed()) {
    editWindow.close();
  }
});

// 删除窗口管理
const deleteDialogWindows = new Map<string, BrowserWindow>();

function resolveDeleteDialogUrl(connectionId: string, connectionData: any): string {
  const params = new URLSearchParams();
  params.set('connectionId', connectionId);
  if (connectionData) {
    params.set('id', connectionData.id || '');
    params.set('ip', connectionData.ip || '');
    params.set('port', String(connectionData.port || ''));
    params.set('label', connectionData.label || '');
  }
  const hash = `#/delete-connection?${params.toString()}`;
  if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
    const url = `${process.env['ELECTRON_RENDERER_URL']}${hash}`;
    return url;
  }
  const fileUrl = pathToFileURL(join(__dirname, '../renderer/index.html'));
  fileUrl.hash = hash;
  const finalUrl = fileUrl.toString();
  return finalUrl;
}

// 创建删除窗口
ipcMain.handle('dialog-show-delete-connection', async (_event, connectionData) => {
  try {
    const targetWindow = ensureMainWindow();
    const connectionId = connectionData?.id || `delete-${Date.now()}`;
    const existingWindow = deleteDialogWindows.get(connectionId);
    if (existingWindow && !existingWindow.isDestroyed()) {
      existingWindow.close();
      deleteDialogWindows.delete(connectionId);
    }

    const dialogUrl = resolveDeleteDialogUrl(connectionId, connectionData);
    const mainBounds = targetWindow.getBounds();
    const windowWidth = 400;
    const windowHeight = 300;
    const x = Math.round(mainBounds.x + (mainBounds.width - windowWidth) / 2);
    const y = Math.round(mainBounds.y + (mainBounds.height - windowHeight) / 2);

    const deleteWindow = new BrowserWindow({
      parent: targetWindow,
      modal: true,
      width: windowWidth,
      height: windowHeight,
      x: x,
      y: y,
      resizable: true,
      minimizable: false,
      show: false,
      autoHideMenuBar: true,
      ...(process.platform === 'linux' ? { icon } : {}),
      webPreferences: {
        preload: join(__dirname, '../preload/index.js'),
        sandbox: false,
        contextIsolation: true,
        nodeIntegration: false
      }
    });

    deleteDialogWindows.set(connectionId, deleteWindow);
    const confirmHandler = (event: any, payload: any) => {
      try {
        if (event?.sender !== deleteWindow.webContents) return;
        if (mainWindow && !mainWindow.isDestroyed()) {
          mainWindow.webContents.send('delete-connection-confirmed', payload);
        }
        if (!deleteWindow.isDestroyed()) deleteWindow.close();
      } catch (err) {
        console.error('Error handling delete confirm:', err);
      }
    };

    const cancelHandler = (event: any) => {
      try {
        if (event?.sender !== deleteWindow.webContents) return;
        if (!deleteWindow.isDestroyed()) deleteWindow.close();
      } catch (err) {
        console.error('Error handling delete cancel:', err);
      }
    };

    ipcMain.on('delete-connection-confirm', confirmHandler);
    ipcMain.on('delete-connection-cancel', cancelHandler);

    deleteWindow.on('closed', () => {
      deleteDialogWindows.delete(connectionId);
      ipcMain.removeListener('delete-connection-confirm', confirmHandler);
      ipcMain.removeListener('delete-connection-cancel', cancelHandler);
    });

    deleteWindow.webContents.on('did-fail-load', () => {
      if (!deleteWindow.isDestroyed()) {
        deleteWindow.close();
      }
    });

    deleteWindow.once('ready-to-show', () => {
      console.log('Delete dialog window ready-to-show event fired');
    });

    const loadPromise = new Promise<void>((resolve, reject) => {
      let resolved = false;
      const timeout = setTimeout(() => {
        if (!resolved) {
          resolved = true;
          resolve();
        }
      }, 3000);

      deleteWindow.webContents.once('did-finish-load', () => {
        if (!resolved) {
          resolved = true;
          clearTimeout(timeout);
          resolve();
        }
      });

      deleteWindow.webContents.once('did-fail-load', (_event, _errorCode, errorDescription) => {
        if (!resolved) {
          resolved = true;
          clearTimeout(timeout);
          reject(new Error(`加载失败: ${errorDescription}`));
        }
      });
    });

    try {
      await deleteWindow.loadURL(dialogUrl);
      await loadPromise;

      if (!deleteWindow.isDestroyed()) {
        deleteWindow.show();
        deleteWindow.focus();
      }
    } catch (loadError) {
      if (!deleteWindow.isDestroyed()) {
        deleteWindow.close();
      }
      throw loadError;
    }

    return { success: true, connectionId };
  } catch (error) {
    return { success: false, error: error instanceof Error ? error.message : String(error) };
  }
});

// 信任站点列表窗口管理
let trustedSitesListWindow: BrowserWindow | null = null;

function resolveTrustedSitesListUrl(): string {
  const hash = '#/trusted-sites-list';
  if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
    const url = `${process.env['ELECTRON_RENDERER_URL']}${hash}`;
    return url;
  }
  const fileUrl = pathToFileURL(join(__dirname, '../renderer/index.html'));
  fileUrl.hash = hash;
  const finalUrl = fileUrl.toString();
  return finalUrl;
}

// 创建信任站点列表窗口
ipcMain.handle('dialog-show-trusted-sites-list', async () => {
  try {
    const targetWindow = ensureMainWindow();

    // 如果窗口已存在，则聚焦到该窗口
    if (trustedSitesListWindow && !trustedSitesListWindow.isDestroyed()) {
      trustedSitesListWindow.focus();
      return { success: true };
    }

    const dialogUrl = resolveTrustedSitesListUrl();

    const mainBounds = targetWindow.getBounds();
    const windowWidth = 600;
    const windowHeight = 400;
    const x = Math.round(mainBounds.x + (mainBounds.width - windowWidth) / 2);
    const y = Math.round(mainBounds.y + (mainBounds.height - windowHeight) / 2);

    const trustedWindow = new BrowserWindow({
      parent: targetWindow,
      modal: true,
      width: windowWidth,
      height: windowHeight,
      x: x,
      y: y,
      resizable: true,
      minimizable: false,
      show: false,
      autoHideMenuBar: true,
      ...(process.platform === 'linux' ? { icon } : {}),
      webPreferences: {
        preload: join(__dirname, '../preload/index.js'),
        sandbox: false,
        contextIsolation: true,
        nodeIntegration: false
      }
    });

    trustedSitesListWindow = trustedWindow;

    trustedWindow.on('closed', () => {
      trustedSitesListWindow = null;
    });

    trustedWindow.webContents.on('did-fail-load', () => {
      if (!trustedWindow.isDestroyed()) {
        trustedWindow.close();
      }
    });

    trustedWindow.once('ready-to-show', () => {
      console.log('Trusted sites window ready-to-show event fired');
    });

    const loadPromise = new Promise<void>((resolve, reject) => {
      let resolved = false;
      const timeout = setTimeout(() => {
        if (!resolved) {
          resolved = true;
          resolve();
        }
      }, 3000);

      trustedWindow.webContents.once('did-finish-load', () => {
        if (!resolved) {
          resolved = true;
          clearTimeout(timeout);
          resolve();
        }
      });

      trustedWindow.webContents.once('did-fail-load', (_event, _errorCode, errorDescription) => {
        if (!resolved) {
          resolved = true;
          clearTimeout(timeout);
          reject(new Error(`加载失败: ${errorDescription}`));
        }
      });
    });

    try {
      await trustedWindow.loadURL(dialogUrl);
      await loadPromise;

      if (!trustedWindow.isDestroyed()) {
        trustedWindow.show();
        trustedWindow.focus();
      }
    } catch (loadError) {
      if (!trustedWindow.isDestroyed()) {
        trustedWindow.close();
      }
      throw loadError;
    }

    return { success: true };
  } catch (error) {
    return { success: false, error: error instanceof Error ? error.message : String(error) };
  }
});

// 创建帮助窗口
ipcMain.handle('dialog-show-help', async () => {
  try {
    const targetWindow = ensureMainWindow();

    if (helpWindow && !helpWindow.isDestroyed()) {
      helpWindow.focus();
      return { success: true };
    }

    const dialogUrl = resolveHelpUrl();

    const mainBounds = targetWindow.getBounds();
    const windowWidth = 800;
    const windowHeight = 560;
    const x = Math.round(mainBounds.x + (mainBounds.width - windowWidth) / 2);
    const y = Math.round(mainBounds.y + (mainBounds.height - windowHeight) / 2);

    const helpWin = new BrowserWindow({
      parent: targetWindow,
      modal: true,
      width: windowWidth,
      height: windowHeight,
      x,
      y,
      resizable: true,
      minimizable: false,
      show: false,
      autoHideMenuBar: true,
      ...(process.platform === 'linux' ? { icon } : {}),
      webPreferences: {
        preload: join(__dirname, '../preload/index.js'),
        sandbox: false,
        contextIsolation: true,
        nodeIntegration: false
      }
    });

    helpWindow = helpWin;

    helpWin.on('closed', () => {
      helpWindow = null;
    });

    helpWin.webContents.on('did-fail-load', () => {
      if (!helpWin.isDestroyed()) {
        helpWin.close();
      }
    });

    const loadPromise = new Promise<void>((resolve, reject) => {
      let resolved = false;
      const timeout = setTimeout(() => {
        if (!resolved) {
          resolved = true;
          resolve();
        }
      }, 3000);

      helpWin.webContents.once('did-finish-load', () => {
        if (!resolved) {
          resolved = true;
          clearTimeout(timeout);
          resolve();
        }
      });

      helpWin.webContents.once('did-fail-load', (_event, _errorCode, errorDescription) => {
        if (!resolved) {
          resolved = true;
          clearTimeout(timeout);
          reject(new Error(`加载失败: ${errorDescription}`));
        }
      });
    });

    await Promise.race([
      loadPromise,
      (async () => {
        await helpWin.loadURL(dialogUrl);
      })()
    ]);

    if (!helpWin.isDestroyed()) {
      helpWin.show();
      helpWin.focus();
    }

    return { success: true };
  } catch (error) {
    console.error('Failed to open help window:', error);
    return { success: false, error: error instanceof Error ? error.message : String(error) };
  }
});
